package org.particlethink.mapper.impl;

import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.particlethink.exception.TokenException;
import org.particlethink.model.Supplier;
import org.particlethink.utils.PathUtil;

import java.io.IOException;
import java.net.URISyntaxException;
import java.util.*;
import java.util.stream.Collectors;

public class ProMaterialRequestHelper {
    private final static String majorTypesUrl = "/material/api/getTree";
    private final static String materialUrl = "/material/details/list";
    private final static String supplierUrl = "/material/supplier";
    private final static ObjectMapper objectMapper = new ObjectMapper();

    public static List<MajorType> listMajorTypes(String url, String token) throws URISyntaxException, IOException {
        url = PathUtil.mergeUrlPaths(url, majorTypesUrl);

        List<MajorType> result;

        try (HttpResponse response = HttpUtil.createGet(url).header("Authorization", "Bearer " + token).execute()) {
            TypeResponse resp = objectMapper.readValue(response.bodyBytes(), TypeResponse.class);
            if (resp.code == 401) {
                throw new TokenException();
            }

            result = new ArrayList<>(resp.getData());
        }

        return result;
    }

    public static MaterialResponse listMaterials(
            String url,
            String token,
            List<Integer> ids,
            List<String> materialCodes,
            List<String> codes,
            Integer pageNum,
            Integer pageSize
    ) throws URISyntaxException, IOException {
        url = PathUtil.mergeUrlPaths(url, materialUrl);
        List<Material> result;
        Map<String, Object> params = new HashMap<>();

        if (ids != null && !ids.isEmpty()) {

            params.put("idList", ids.stream().filter(t -> t != null && t != 0).collect(Collectors.toList()));
        }
        if (materialCodes != null && !materialCodes.isEmpty()) {
            params.put("materialCode", materialCodes.stream().filter(t -> t != null && !t.isEmpty()).collect(Collectors.toList()));
        }

        if (codes != null && !codes.isEmpty()) {
            params.put("codeList", codes.stream().filter(t -> t != null && !t.isEmpty()).collect(Collectors.toList()));

        }
        if (pageNum == null || pageNum.equals(0)) {
            pageNum = 1;
        }
        params.put("pageNum", pageNum);
        if (pageSize == null || pageSize.equals(0)) {
            pageSize = 100;
        }

        params.put("pageSize", pageSize);

        try (HttpResponse response = HttpUtil.createPost(url).body(objectMapper.writeValueAsString(params), "application/json").header("Authorization", "Bearer " + token).execute()) {
            MaterialResponse resp = objectMapper.readValue(response.bodyBytes(), MaterialResponse.class);
            if (resp.code == 401) {
                throw new TokenException();
            }

            return resp;

        }
    }


    public static List<Supplier> suppliersByParentCategoryId(String parentCategoryCode, String url, String token) throws URISyntaxException, IOException {

        List<Supplier> suppliers = new ArrayList<>();

        url = PathUtil.mergeUrlPaths(url, supplierUrl);

        try (HttpResponse response = HttpUtil.createGet(url + "?majorCode=" + parentCategoryCode).header("Authorization", "Bearer " + token).execute()) {
            ProSupplierRequestHelper.SupplierResponse resp = objectMapper.readValue(response.bodyBytes(), ProSupplierRequestHelper.SupplierResponse.class);
            if (resp.getCode() == 401) {
                throw new TokenException();
            }

            resp.getData().forEach(row -> suppliers.add(new Supplier(row.getId(), null, null, row.getName(), row.getResourceId())));
            return suppliers;

        }


    }

    public static class TypeResponse {
        private String msg;
        private Integer code;
        private List<MajorType> data;

        public String getMsg() {
            return msg;
        }

        public void setMsg(String msg) {
            this.msg = msg;
        }

        public Integer getCode() {
            return code;
        }

        public void setCode(Integer code) {
            this.code = code;
        }

        public List<MajorType> getData() {
            return data;
        }

        public void setData(List<MajorType> data) {
            this.data = data;
        }
    }

    public static class MajorType {
        private String majorName;
        private String majorCode;
        private List<MinorType> minorType;

        public String getMajorName() {
            return majorName;
        }

        public void setMajorName(String majorName) {
            this.majorName = majorName;
        }

        public List<MinorType> getMinorType() {
            return minorType;
        }

        public void setMinorType(List<MinorType> minorType) {
            this.minorType = minorType;
        }

        public String getMajorCode() {
            return majorCode;
        }

        public void setMajorCode(String majorCode) {
            this.majorCode = majorCode;
        }
    }

    public static class MinorType {
        private String minorName;
        private String minorCode;

        public String getMinorName() {
            return minorName;
        }

        public void setMinorName(String minorName) {
            this.minorName = minorName;
        }

        public String getMinorCode() {
            return minorCode;
        }

        public void setMinorCode(String minorCode) {
            this.minorCode = minorCode;
        }
    }

    public static class MaterialResponse {
        private Integer total;
        private String msg;
        private Integer code;
        private List<Material> rows;

        public String getMsg() {
            return msg;
        }

        public void setMsg(String msg) {
            this.msg = msg;
        }

        public Integer getCode() {
            return code;
        }

        public void setCode(Integer code) {
            this.code = code;
        }


        public Integer getTotal() {
            return total;
        }

        public void setTotal(Integer total) {
            this.total = total;
        }

        public List<Material> getRows() {
            return rows;
        }

        public void setRows(List<Material> rows) {
            this.rows = rows;
        }
    }


    public static class Material {
        private String type;
        private List<MaterialDetail> materialDetails;
        private Integer total;//返回用

        public String getType() {
            return type;
        }

        public void setType(String type) {
            this.type = type;
        }

        public List<MaterialDetail> getMaterialDetails() {
            return materialDetails;
        }

        public void setMaterialDetails(List<MaterialDetail> materialDetails) {
            this.materialDetails = materialDetails;
        }

        public Integer getTotal() {
            return total;
        }

        public void setTotal(Integer total) {
            this.total = total;
        }
    }


    public static class MaterialDetail {
        private Integer id;
        private String name;
        private String code;
        private String materialDetail;
        private String materialCategory;
        private String specification;
        private String model;
        private String unit;
        private String qualityStandard;
        private String description;


        public Integer getId() {
            return id;
        }

        public void setId(Integer id) {
            this.id = id;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public String getCode() {
            return code;
        }

        public void setCode(String code) {
            this.code = code;
        }

        public String getCategoryId() {
            return this.code.substring(0, 4);
        }

        public String getParentCategoryId() {
            return this.code.substring(0, 2);
        }


        public String getMaterialDetail() {
            return materialDetail;
        }

        public void setMaterialDetail(String materialDetail) {
            this.materialDetail = materialDetail;
        }

        public String getSpecification() {
            return specification;
        }

        public void setSpecification(String specification) {
            this.specification = specification;
        }

        public String getModel() {
            return model;
        }

        public void setModel(String model) {
            this.model = model;
        }

        public String getUnit() {
            return unit;
        }

        public void setUnit(String unit) {
            this.unit = unit;
        }

        public String getQualityStandard() {
            return qualityStandard;
        }

        public void setQualityStandard(String qualityStandard) {
            this.qualityStandard = qualityStandard;
        }

        public String getDescription() {
            return description;
        }

        public void setDescription(String description) {
            this.description = description;
        }

        public String getMaterialCategory() {
            return materialCategory;
        }

        public void setMaterialCategory(String materialCategory) {
            this.materialCategory = materialCategory;
        }
    }
}
